package edu.whut.mall.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import edu.whut.mall.common.constant.WxPayConstant;
import edu.whut.mall.common.dao.IRedisDao;
import edu.whut.mall.common.dto.*;
import edu.whut.mall.common.util.CommonUtil;
import edu.whut.mall.common.util.RandomUtils;
import edu.whut.mall.common.util.WxPayApi;
import edu.whut.mall.common.util.WxPayKit;
import edu.whut.mall.common.enums.AccountType;
import edu.whut.mall.common.enums.WxTradeType;
import edu.whut.mall.pojo.mapper.*;
import edu.whut.mall.pojo.model.*;
import edu.whut.mall.user.service.IPayService;
import edu.whut.mall.user.service.ITradeService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;


@Service
@Slf4j
public class PayServiceImpl implements IPayService {


//    @Resource
//    private IConfigService configService;
//    @Resource
//    private IProductSellService productSellService;

    @Resource
    private TradeRefundMapper tradeRefundMapper;

    @Resource
    private RefundMapper refundMapper;

    @Resource
    private TradeMapper tradeMapper;

    @Resource
    private ITradeService tradeService;

    @Resource
    private UserMapper userMapper;

    @Resource
    private OrderMapper orderMapper;

    @Resource
    private IRedisDao<String, String> redisDao;

    @Resource
    private ProductMapper productMapper;

    @Resource
    private ProductSellMapper productSellMapper;

    @Value("${wxnotify.trade.url.notify}")
    private String TRADE_URL_NOTIFY;

    @Value("${wxnotify.url.notify}")
    private String URL_NOTIFY;

    @Resource
    private RedissonClient redissonClient;

    static final Map<String, WxPayAccount> WX_PAY_ACCOUNT_MAP = new ConcurrentHashMap<>(2);

    @Override
    public Integer confirmPayStatus(String outTradeNo) {
        //根据out_trade_no查出订单
        RLock payLock = redissonClient.getLock("wxpayLock-" + outTradeNo);
        // 尝试拿锁10s后停止重试,返回false
        // 具有Watch Dog 自动延期机制 默认续30s
        payLock.lock(30, TimeUnit.SECONDS);
        try {
            Trade tradeVo = tradeMapper.getTradeByOutTradeNo(outTradeNo);
            if (null != tradeVo && null == tradeVo.getPayTime()) {
                // 更新支付状态,具有防止重复调用的作用
                tradeService.pay(tradeVo.getId());
                return tradeVo.getId();
            }
        } finally {
            payLock.unlock();
        }
        return -1;
    }

    /**
     * 微信支付订单退款,退款先不写
     *
     * @param user
     * @param clinetIp
     * @param outTradeNo
     * @param refundFee
     * @param totalFee
     * @return
     * @throws Exception
     */
    @Override
    public Integer orderRefund(Integer user, String clinetIp, String outTradeNo, Double refundFee, Double totalFee) throws Exception {

        //使用参数的方式获取参数
        WxPayAccount wxPayAccount = getWxPayAccount();
        Integer flag = orderRefund(user, clinetIp, outTradeNo, refundFee, totalFee, wxPayAccount);
        if (flag < 0) {
            if (AccountType.CHANGEBUY.getType().equals(wxPayAccount.getAccountName())) {
                WxPayAccount wxPayAccount1 = getWxPayAccount(AccountType.CHANGE);
                return orderRefund(user, clinetIp, outTradeNo, refundFee, totalFee, wxPayAccount1);
            } else {
                WxPayAccount wxPayAccount2 = getWxPayAccount(AccountType.CHANGEBUY);
                return orderRefund(user, clinetIp, outTradeNo, refundFee, totalFee, wxPayAccount2);
            }
        }

        return flag;
    }

    private Integer orderRefund(Integer user, String clinetIP, String outTradeNo, Double refundFee, Double totalFee, WxPayAccount wxPayAccount) throws Exception {
        //将微信支付退款金额转为分
        int refund_fee = (int) (refundFee.doubleValue() * 100);
        int total_fee = (int) (totalFee.doubleValue() * 100);

        //封装请求信息
        Map<String, String> map = new RefundModel()
                .setAppid(wxPayAccount.getApp_id())
                .setMch_id(wxPayAccount.getMch_id())
                .setNonce_str(RandomUtils.generateMixString(30))
                .setOut_trade_no(outTradeNo)
                .setOut_refund_no(CommonUtil.getOutRefundNo())
                .setRefund_fee(String.valueOf(refund_fee))
                .setTotal_fee(String.valueOf(total_fee))
                .creatSign(wxPayAccount.getApp_key());


        String xml = WxPayKit.toXml(map);
        log.info("------" + xml);

        //开始进行退款
        String responseXml = WxPayApi.orderRefund(map, wxPayAccount.getCert_path(), wxPayAccount.getMch_id());
        log.info(responseXml);
        Map<String, String> result = WxPayKit.toMap(responseXml);

        TradeOrderRefund tradeOrderRefund = TradeOrderRefund.builder()
                .user(user)
                .refundFee(refundFee)
                .totalFee(totalFee)
                .clientIP(clinetIP)
                .outTradeNo(outTradeNo)
                .createTime(new Date())
                .updateTime(new Date())
                .paidAccount(wxPayAccount.getAccountName())
                .build();
        String return_code = result.get("return_code");
        String return_msg = result.get("return_msg");
        String result_code = result.get("result_code");
        if (return_code != null && !return_code.isEmpty() && "SUCCESS".equals(return_code)) {
            //业务代码
            if (result_code != null && !result_code.isEmpty() && !"SUCCESS".equals(result_code)) {
                String err_code_des = result.get("err_code_des");
                //退款失败，将数据存储到数据库中，没有订单号和退款号
                tradeOrderRefund.setPaid(0);
                tradeOrderRefund.setMessage(err_code_des);
                tradeRefundMapper.insert(tradeOrderRefund);
                if ("订单已全额退款".equals(err_code_des)) {
                    log.info(err_code_des);
                    return 1;
                }
                log.error("退款失败！");
                return -1;
            } else {
                //退款成功，将数据存储到数据库中
                tradeOrderRefund.setOutRefundNo(map.get("out_refund_no"));
                tradeOrderRefund.setNonceStr(map.get("nonce_str"));
                tradeOrderRefund.setPaid(1);
                tradeOrderRefund.setMessage("付款成功");

                tradeRefundMapper.insert(tradeOrderRefund);
                return 1;
            }
        } else {
            //记录出现错误的单号信息
            tradeOrderRefund.setPaid(0);
            tradeOrderRefund.setMessage(return_msg);
            tradeRefundMapper.insert(tradeOrderRefund);
            return -1;
        }
    }

    /**
     * 微信退款通用接口
     *
     * @param userId     用户id
     * @param outTradeNo 订单号
     * @param clientIP   ip
     * @return
     * @throws Exception
     */
    @Override
    public Integer refund(int userId, String outTradeNo, String clientIP) throws Exception {
        Double totalMoney = refundMapper.getRefundMoney(outTradeNo);
        if (totalMoney == null || totalMoney <= 0) {
            return -1;
        } else {
            return orderRefund(userId, clientIP, outTradeNo, totalMoney, totalMoney);
        }
    }

    /**
     * 根据支付账户的设置，配置相应的账户信息
     *
     * @return
     * @throws Exception
     */
    @Override
    public WxPayAccount getWxPayAccount() {
        return getWxPayAccount(AccountType.CHANGE);
    }

    /**
     * 获取特定商户信息
     *
     * @param accountType
     * @return
     * @throws Exception
     */
    @Override
    public WxPayAccount getWxPayAccount(AccountType accountType) {
        if (accountType == AccountType.CHANGE) {
            //当前账户为嫦娥抗衰账号
            //缓存处理
            WxPayAccount wxPayAccount = WX_PAY_ACCOUNT_MAP.get(accountType.toString());
            if (wxPayAccount == null) {
                wxPayAccount = new WxPayAccount(accountType.getType(), WxPayConstant.CHANGE_APP_APPID, WxPayConstant.CHANGE_KEY, WxPayConstant.CHANGE_MCHID, WxPayConstant.CHANGE_APP_APPSECRET, WxPayConstant.CHANGE_MINIPROGRAM_APPID, WxPayConstant.CHANGE_MINIPROGRAM_APPSECRET,
                        WxPayConstant.CHANGE_CERT_PATH, URL_NOTIFY, TRADE_URL_NOTIFY);
                //加入缓存当中
                WX_PAY_ACCOUNT_MAP.put(accountType.toString(), wxPayAccount);
            }
            return wxPayAccount;
        }
        return null;
    }

//    @Override
//    public WxPayAccount getWithdrawAccount(){
//        Integer wxpay_account = (Integer) configService.getConfig("withdraw_account");
//        if (wxpay_account == 0) {
//            //当前账户为嫦娥抗衰账号
//            return getWxPayAccount(AccountType.CHANGE);
//        }
//        if (wxpay_account == 1) {
//            //当前账户为变购链
//            return getWxPayAccount(AccountType.CHANGEBUY);
//        }
//        return null;
//    }

//    @Override
//    public WxPayAccount getWithdrawAccount(AccountType accountType) throws Exception {
//        return getWxPayAccount(accountType);
//    }


    /**
     * 微信退款查询，退款方面先不写
     *
     * @param outTradeNo
     * @return
     * @throws Exception
     */
//    @Override
//    public String refundQuery(String outTradeNo){
//        OrderRefundVo orderRefundVo = payMapper.getRefundByOutTradeNo(outTradeNo);
//        if (orderRefundVo != null) {
//            return orderRefundVo.getMessage();
//        }
//        //向微信支付查询订单状况
//        WxPayAccount wxPayAccount = getWxPayAccount();
//        Map<String, String> map = new RefundQueryModel()
//                .setAppid(wxPayAccount.getApp_id())
//                .setMch_id(wxPayAccount.getMch_id())
//                .setNonce_str(RandomUtils.generateString(30))
//                .setOut_trade_no(outTradeNo)
//                .creatSign(wxPayAccount.getApp_key());
//
//
//        String xml = WxPayKit.toXml(map);
//        log.info("发送xml:" + xml);
//
//        //退款查询
//        String responseXml = WxPayApi.orderRefundQuery(map);
//        log.info(responseXml);
//        Map<String, String> result = WxPayKit.toMap(responseXml);
//
//
//        //系统代码
//        String return_code = result.get("return_code");
//        String return_msg = result.get("return_msg");
//        //业务代码
//        String result_code = result.get("result_code");
//
//        //系统代码
//        if (return_code != null && !return_code.isEmpty() && return_code.equals("SUCCESS")) {
//            //业务代码
//            if (result_code != null && !result_code.isEmpty() && !result_code.equals("SUCCESS")) {
//                String err_code_des = result.get("err_code_des");
//                //退款失败，将数据存储到数据库中，没有订单号和退款号
//                log.info(err_code_des);
//                return err_code_des;
//            }
//        } else {
//            //记录出现错误的单号信息
//            return return_msg;
//        }
//        return "无查询结果";
//    }

    /**
     * 企业付款到零钱，可用于提现功能，零钱体现先不写
     * @param openId
     * @param money
     * @param description
     * @param wxPayAccount
     * @param type
     * @return
     * @throws Exception
     */
//    @Override
//    public Integer companyToChange(String openId, Double money, String description, WxPayAccount wxPayAccount, Integer type) throws Exception {
//        money = NumberUtil.keepTwoPrecision(money);
//        //金额转为分
//        int amount = (int) (money * 100);
//        String mch_appid = "";
//        String mchid = "";
//        if (type == null || type == 0) {
//            mch_appid = wxPayAccount.getMiniprogram_app_id();
//            mchid = wxPayAccount.getMch_id();
//        }
//        if (type == 1) {
//            mch_appid = wxPayAccount.getApp_id();
//            mchid = wxPayAccount.getMch_id();
//        }
//        Map<String, String> map = new CompanyToChangeModel()
//                .setMch_appid(mch_appid)
//                .setMchid(mchid)
//                .setNonce_str(RandomUtils.generateString(30))
//                .setPartner_trade_no(CommonUtil.getPartnerTradeNo())
//                .setOpenid(openId)
//                .setAmount(String.valueOf(amount))
//                .setCheck_name("NO_CHECK")
//                .setDesc(description)
//                .creatSign(wxPayAccount.getApp_key());
//
//        String xml = WxPayKit.toXml(map);
//        log.info("企业付款xml------" + xml);
//
//        //开始企业付款
//        String responseXml = WxPayApi.transfers(map, wxPayAccount.getCert_path(), wxPayAccount.getMch_id());
//        log.info(responseXml);
//
//        Map<String, String> result = WxPayKit.toMap(responseXml);
//
//        //系统代码
//        String return_code = result.get("return_code");
//        String return_msg = result.get("return_msg");
//        //业务代码
//        String result_code = result.get("result_code");
//
//        //系统代码
//        if (return_code != null && !return_code.isEmpty() && return_code.equals("SUCCESS")) {
//            //业务代码
//            if (result_code != null && !result_code.isEmpty() && !result_code.equals("SUCCESS")) {
//                String err_code_des = result.get("err_code_des");
//                //企业付款失败
//                log.info("提现失败，错误原因:" + err_code_des);
//                return -1;
//            } else {
//                //企业付款成功
//                log.info("企业付款成功，付款金额：{} 付款商户：{}", money, wxPayAccount.getAccountName());
//                return 1;
//            }
//        } else {
//            //记录出现错误的单号信息
//            log.error(return_msg);
//            return -1;
//        }
//
//    }

    /**
     * 提现接口，提现先不写
     *
     * @param openId
     * @param money
     * @param description
     * @param wxPayAccount
     * @param type
     * @return
     * @throws Exception
     */
//    @Override
//    public WeixinReturnInfo withdraw(String openId, Double money, String description, WxPayAccount wxPayAccount, Integer type) throws Exception {
//        money = NumberUtil.keepTwoPrecision(money);
//        //金额转为分
//        int amount = (int) (money * 100);
//        String mch_appid = "";
//        String mchid = "";
//        if (type == null || type == 0) {
//            mch_appid = wxPayAccount.getMiniprogram_app_id();
//            mchid = wxPayAccount.getMch_id();
//        }
//        if (type == 1) {
//            mch_appid = wxPayAccount.getApp_id();
//            mchid = wxPayAccount.getMch_id();
//        }
//        Map<String, String> map = new CompanyToChangeModel()
//                .setMch_appid(mch_appid)
//                .setMchid(mchid)
//                .setNonce_str(RandomUtils.generateString(30))
//                .setPartner_trade_no(CommonUtil.getPartnerTradeNo())
//                .setOpenid(openId)
//                .setAmount(String.valueOf(amount))
//                .setCheck_name("NO_CHECK")
//                .setDesc(description)
//                .creatSign(wxPayAccount.getApp_key());
//
//        String xml = WxPayKit.toXml(map);
//        log.info("企业付款xml------" + xml);
//
//        //开始企业付款
//        String responseXml = WxPayApi.transfers(map, wxPayAccount.getCert_path(), wxPayAccount.getMch_id());
//        log.info(responseXml);
//
//        Map<String, String> result = WxPayKit.toMap(responseXml);
//
//        //系统代码
//        String return_code = result.get("return_code");
//        String return_msg = result.get("return_msg");
//        //业务代码
//        String result_code = result.get("result_code");
//
//        //系统代码
//        if (return_code != null && !return_code.isEmpty() && return_code.equals("SUCCESS")) {
//            //业务代码
//            if (result_code != null && !result_code.isEmpty() && !result_code.equals("SUCCESS")) {
//                String err_code_des = result.get("err_code_des");
//                //企业付款失败
//                log.info("提现失败，错误原因:{}", err_code_des);
//                return null;
//            } else {
//                //企业付款成功
//                log.info("企业付款成功，付款金额：{}", money);
//                WeixinReturnInfo weixinReturnInfo = new WeixinReturnInfo(result.get("payment_no"), result.get("payment_time"));
//                return weixinReturnInfo;
//            }
//        } else {
//            //记录出现错误的单号信息
//            log.error(return_msg);
//            return null;
//        }
//    }

    /**
     * 订单状态查询
     *
     * @param outTradeNo
     * @return
     * @throws Exception
     */
    @Override
    public String orderQuery(String outTradeNo) throws Exception {
        //向微信支付查询订单状况
        WxPayAccount wxPayAccount = getWxPayAccount();
        Map<String, String> map = new OrderQueryModel()
                .setAppid(wxPayAccount.getApp_id())
                .setMch_id(wxPayAccount.getMch_id())
                .setNonce_str(RandomUtils.generateString(30))
                .setOut_trade_no(outTradeNo)
                .creatSign(wxPayAccount.getApp_key());

        String xml = WxPayKit.toXml(map);

        //退款查询
        String responseXml = WxPayApi.orderQuery(map);
//        log.info(responseXml);
        Map<String, String> result = WxPayKit.toMap(responseXml);

        //系统代码
        String return_code = result.get("return_code");
        String return_msg = result.get("return_msg");
        //业务代码
        String result_code = result.get("result_code");

        //系统代码
        if (return_code != null && !return_code.isEmpty() && return_code.equals("SUCCESS")) {
            //业务代码
            if (result_code != null && !result_code.isEmpty() && result_code.equals("SUCCESS")) {
                //查询成功
                String trade_state = result.get("trade_state");
                log.info("订单号：{}", outTradeNo + " 订单状态：" + trade_state);
                return trade_state;
            } else {
                String err_code_des = result.get("err_code_des");
                //退款失败，将数据存储到数据库中，没有订单号和退款号
                log.info(err_code_des);
                return err_code_des;
            }
        } else {
            //记录出现错误的单号信息
            return return_msg;
        }
    }

    /**
     * 1 确认商品信息和商品库存
     * 2 请求微信后台获取preId
     * 3 存储订单信息
     * 4 返回订单支付信息
     *
     * @param request
     * @param userId
     * @param openid
     * @param tradeId
     * @param type
     * @return
     * @throws Exception
     */
    @Override
    public String prePay(HttpServletRequest request, Integer userId, String openid, Integer tradeId, int type, WxTradeType wxTradeType) throws Exception {
        Map<String, Object> map = new HashMap<>();
        ObjectMapper mapper = new ObjectMapper();
        boolean result = true;
        String info = "";
        String openId = openid;
        if (userId != null && openId == null) {
            User user = userMapper.selectById(userId);
            openId = user.getOpenId();
            if (openId != null) {
                openId = openId.replace("\"", "").trim();
            }
        }

        //1.获得客户ip地址
        String clientIp = CommonUtil.getClientIp(request);
        log.info("openId: {}, clientIP:{}", openId, clientIp);
        String randomNonceStr = RandomUtils.generateMixString(30);

        //调用支付接口获取prepayId
        if (type == 0) {
            Trade trade = tradeMapper.selectById(tradeId);
            String orderNumber = trade.getSubOrderNumber();
            double money = trade.getTotalMoney();
            LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Order::getTradeId, tradeId);
            List<Order> orderList = orderMapper.selectList(queryWrapper);
            String productName = null;
            for (int i = 0; i < orderList.size(); i++) {
                Order order = orderList.get(i);
                Integer productNumRest = productSellMapper.getProductSellNumRest(order.getProductId());
                log.info("库存剩余： " + productNumRest);
                if (order.getQuantity() > productNumRest) {
                    result = false;
                    info = "出错了，库存不够";
                }
                Product product = productMapper.selectById(order.getProductId());
                if (i != 0 && productName != null && productName.length() < 32) {
                    productName = productName + " 和 " + product.getName();
                } else {
                    productName = product.getName();
                }
            }
            //2.调用统一下单接口
            Map<String, String> information = unifiedOrderNew(openId, clientIp, "重构项目-" + productName, orderNumber, randomNonceStr, money, 1, wxTradeType);

            //3 返回微信支付信息
            if (information.containsKey("prepay_id") && information.containsKey("sign")) {
                log.info("prepayId: " + information.get("prepay_id"));

                if (WxTradeType.APP == wxTradeType) {
                    map.put("prepayId", information.get("prepay_id"));
                    map.put("nonceStr", randomNonceStr);
                    map.put("sign", information.get("sign"));
                }
                if (WxTradeType.JSAPI == wxTradeType) {
                    map.put("prepayId", information.get("prepay_id"));
                    map.put("nonceStr", randomNonceStr);
                }
            } else {
                result = false;
                info = "出错了，未获取到prepayId";
            }
        }

        map.put("result", result);
        map.put("info", info);
        String content = mapper.writeValueAsString(map);
        return content;
    }

    /**
     * 统一下单支付方法：
     * 1.封装订单信息
     * 2.请求微信支付接口
     * 3.获取微信支付回返信息
     *
     * @param openId
     * @param clientIP
     * @param productName
     * @param orderNumber
     * @param randomNonceStr
     * @param money
     * @param flag
     * @param wxTradeType
     * @return
     * @throws Exception
     */
    @Override
    public Map<String, String> unifiedOrderNew(String openId, String clientIP, String productName, String orderNumber, String randomNonceStr, double money, int flag, WxTradeType wxTradeType) throws Exception {
        //0  订单信息存储到redis，便于查询支付信息,两天的有效期，到时自动删除
        redisDao.put(WxPayConstant.WXPAY_REDIS_PREFIX + orderNumber, orderNumber, 2, TimeUnit.DAYS);
        Map<String, String> map = new HashMap<>();
        // 1 封装统一下单信息
        WxPayAccount wxPayAccount = getWxPayAccount();
        String notify_url = "";
        if (flag == 1) {
            notify_url = wxPayAccount.getTrade_url_notify();
        }
        if (flag == 2) {
            notify_url = wxPayAccount.getUrl_notify();
        }

        //金额转化成分
        int total_fee = (int) (money * 100);
        //封装请求的model
        Map<String, String> unifiedOrderModelMap = null;
        UnifiedOrderModel unifiedOrderModel = new UnifiedOrderModel()
                .setNonce_str(randomNonceStr)
                .setTotal_fee(String.valueOf(total_fee))
                .setBody(productName)
                .setOut_trade_no(orderNumber)
                .setSpbill_create_ip(clientIP)
                .setNotify_url(notify_url);


        if (WxTradeType.APP == wxTradeType) {
            unifiedOrderModelMap = unifiedOrderModel.setAppid(wxPayAccount.getApp_id())
                    .setMch_id(wxPayAccount.getMch_id())
                    .setTrade_type(wxTradeType.getTradeType())
                    .creatSign(wxPayAccount.getApp_key());
        }

        if (WxTradeType.JSAPI == wxTradeType) {
            unifiedOrderModelMap = unifiedOrderModel.setAppid(wxPayAccount.getMiniprogram_app_id())
                    .setMch_id(wxPayAccount.getMch_id())
                    .setOpenid(openId)
                    .setTrade_type(wxTradeType.getTradeType())
                    .creatSign(wxPayAccount.getApp_key());
        }

        //2 请求微信支付后台
        String xml = WxPayKit.toXml(unifiedOrderModelMap);
        log.info("微信支付请求前参数：{}", xml);
        //开始付款支付
        String responseXml = WxPayApi.pushOrder(unifiedOrderModelMap);
        log.info("微信支付请求返回：{}", responseXml);
        Map<String, String> result = WxPayKit.toMap(responseXml);


        //3 获取详情 打印返回参数
        for (Map.Entry<String, String> entry : result.entrySet()) {
            log.info("属性： {} ，值： {}", entry.getKey(), entry.getValue());
        }

        //系统代码
        String returnCode = result.get("return_code");
        //业务代码
        String resultCode = result.get("result_code");
        if (returnCode != null && !returnCode.isEmpty() && returnCode.equals("SUCCESS")) {
            //业务代码
            if (resultCode != null && !resultCode.isEmpty() && resultCode.equals("SUCCESS")) {
                String prepayId = result.get("prepay_id");
                map.put("prepay_id", prepayId);
                map.put("sign", unifiedOrderModelMap.get("sign"));
                return map;
            } else {
                //重复单号问题
                if (result.get("err_code_des") != null && "201 商户订单号重复".equals(result.get("err_code_des"))) {
                    orderNumber = updateTradeOrderNumber(orderNumber);
                    return unifiedOrderNew(openId, clientIP, productName, orderNumber, randomNonceStr, money, flag, wxTradeType);
                }
                return map;
            }
        } else {
            return map;
        }
    }

    /**
     * 微信支付关闭订单
     *
     * @param orderNumber
     * @param randomNonceStr
     * @param wxTradeType
     * @throws Exception
     */
    public void closeOrder(String orderNumber, String randomNonceStr, WxTradeType wxTradeType) throws Exception {
        log.info("微信支付关闭订单操作");
        CloseOrderModel closeOrderModel = new CloseOrderModel()
                .setNonce_str(randomNonceStr)
                .setOut_trade_no(orderNumber);
        Map<String, String> closeOrderMap = null;
        WxPayAccount wxPayAccount = getWxPayAccount();
        if (WxTradeType.APP == wxTradeType) {
            closeOrderMap = closeOrderModel.setAppid(wxPayAccount.getApp_id())
                    .setMch_id(wxPayAccount.getMch_id())
                    .creatSign(wxPayAccount.getApp_key());
        }

        if (WxTradeType.JSAPI == wxTradeType) {
            closeOrderMap = closeOrderModel.setAppid(wxPayAccount.getMiniprogram_app_id())
                    .setMch_id(wxPayAccount.getMch_id())
                    .creatSign(wxPayAccount.getApp_key());
        }

        //2 请求微信支付后台
        String xml = WxPayKit.toXml(closeOrderMap);
        log.info("微信支付请求前参数：" + xml);
        //开始进行退款
        String responseXml = WxPayApi.closeOrder(closeOrderMap);
        log.info("微信支付请求返回：" + responseXml);
        Map<String, String> result = WxPayKit.toMap(responseXml);


        //3 获取详情 打印返回参数
        for (Map.Entry<String, String> entry : result.entrySet()) {
            log.info("属性： {} ，值： {}", entry.getKey(), entry.getValue());
        }

        //系统代码
        String return_code = result.get("return_code");
        //业务代码
        String result_code = result.get("result_code");
        if (return_code != null && !return_code.isEmpty() && return_code.equals("SUCCESS")) {
            //业务代码
            if (result_code != null && !result_code.isEmpty() && result_code.equals("SUCCESS")) {
                log.info("订单关闭成功");
            } else {
                log.error("关闭订单错误！");
            }
        } else {
            log.error("关闭订单错误！");
        }
    }

    /**
     * 修改订单号
     *
     * @param orderNumber
     * @return
     */
    private String updateTradeOrderNumber(String orderNumber) {
        log.info("原来单号：{}", orderNumber);
        LambdaQueryWrapper<Trade> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Trade::getSubOrderNumber, orderNumber);
        Trade trade = tradeMapper.selectOne(queryWrapper);
        //重新生成单号
        trade.setSubOrderNumber(CommonUtil.getOrderNumber());
        tradeMapper.updateById(trade);
        log.info("新单号：{}", trade.getSubOrderNumber());
        return trade.getSubOrderNumber();
    }

}
